package com.db.priceApp.network.protocol;

import java.nio.channels.SelectionKey;
import java.util.Scanner;
import java.util.logging.Logger;

public class MessageProcessor {


	private Logger logger = Logger.getLogger(MessageProcessor.class.getName());

	public Message processMessage(byte[] inputMessage, String login, SelectionKey clientKey)
			throws IllegalArgumentException {

		String stringInputMesssage = new String(inputMessage);
		
		Message outputMessage = new Message(clientKey, login);		
		Scanner parcer = new Scanner(stringInputMesssage);
		parcer.useDelimiter("\\|");
		
		while (parcer.hasNext()) {						
			tagsAnalizer(parcer.next(), outputMessage);
		}
		parcer.close();
		return outputMessage;
	}

	private void tagsAnalizer(String s, Message message)
			throws IllegalArgumentException {
		Scanner parcer;
		parcer = new Scanner(s);
		parcer.useDelimiter("=");
		int tag;

		if (parcer.hasNext()) {
			
			tag = Integer.parseInt(parcer.next());
			if (!parcer.hasNext()) {
				illegalMessageField(parcer, "empty tag value");
			}
			switch (tag) {
			case 35: // message type
				setMessageType(message, parcer);
				break;
			case 48: // name of the instrument
				setInstrumentName(message, parcer);
				break;
			case 58: // text
				message.setText(parcer.next());
				break;
			case 44: // price
				setInstrumentPrice(message, parcer);
				break;
			case 49: // login
				setLogin(message, parcer);
				break;
			 case 60: //timestamp
				 setTimeStamp(message, parcer);
			 break;
			default:
				illegalMessageField(parcer, "illegal tag " + tag);
			}
			parcer.close();
		}
	}

	private void setTimeStamp(Message message, Scanner parcer) {
		Long timeStamp = 0l;
		try {
			timeStamp = Long.parseLong(parcer.next());
		} catch (NumberFormatException e) {
			illegalMessageField(parcer, "illegal time value");
			throw new IllegalArgumentException("illegal time value");
		}
		message.setTime(timeStamp);		
	}

	private void setLogin(Message message, Scanner parcer) throws IllegalArgumentException {
		String tagValue;
		tagValue = parcer.next();
		if (tagValue == null || tagValue.equals("")){
			logger.warning("empty login");
			throw new IllegalArgumentException("empty login");
		}
		message.setLogin(tagValue);
	}

	private void setInstrumentPrice(Message message, Scanner parcer)
			throws IllegalArgumentException {

		float price = 0;
		try {
			price = Float.parseFloat(parcer.next());
		} catch (NumberFormatException e) {
			illegalMessageField(parcer, "illegal price value");
			throw new IllegalArgumentException("illegal price value");
		}
		message.setPrice(price);

	}

	private void setInstrumentName(Message message, Scanner parcer){
		String tagValue;
		tagValue = parcer.next();
		message.setInstrumentName(tagValue);
	}

	private void setMessageType(Message message, Scanner parcer)
			throws IllegalArgumentException {

		String tagValue;
		tagValue = parcer.next();
		switch (tagValue) {
		case "e": // subscribe-request
			message.setMessageType(MessageType.E);
			break;
		case "U": // unsubscribe-request
			message.setMessageType(MessageType.U);
			break;
		case "V":
			message.setMessageType(MessageType.V);
			break;
		case "Y":
			message.setMessageType(MessageType.Y);
			break;
		case "A":
			message.setMessageType(MessageType.A);
			break;
		case "5":
			message.setMessageType(MessageType.LR);
			break;
		default:
			illegalMessageField(parcer, "Illegal tag value " + tagValue);
		}
	}

	private void illegalMessageField(Scanner parcer, String errorMessage)
			throws IllegalArgumentException {
		parcer.close();
		logger.warning(errorMessage);		
		throw new IllegalArgumentException(errorMessage);
	}

}
